﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Microsoft.Xna.Framework;
using Twodi.Aspect.Interfaces;

namespace Twodi.Structs
{
    public class Bucket<T> where T : IBoundsAspect
    {
        public Bucket(RectangleF bounds)
        {
            Bounds = bounds;
            Objects = new List<T>();
        }

        public RectangleF Bounds
        {
            get;
            protected set;
        }

        public List<T> Objects
        {
            get;
            protected set;
        }
    }

    public class SpatialHashing<T> where T : IBoundsAspect
    {
        public SpatialHashing(Microsoft.Xna.Framework.Rectangle bounds)
            : this(CreateRectangleF(bounds))
        {

        }

        public SpatialHashing(Microsoft.Xna.Framework.Rectangle bounds, Vector2 cellWidht)
            : this(CreateRectangleF(bounds), cellWidht)
        {

        }

        public SpatialHashing(RectangleF bounds)
        {
            this.Bounds = bounds;
        }

        public SpatialHashing(RectangleF bounds, Vector2 cellWidht)
        {
            this.Bounds = bounds;
            CreateBuckets(cellWidht);
        }

        public virtual void CreateBuckets(Vector2 cellWidht)
        {
            int columns = (int)(Bounds.Width / cellWidht.X);
            int lines = (int)(Bounds.Width / cellWidht.Y);

            Buckets = new Bucket<T>[columns, lines];

            for (int y = 0; y < lines; y++)
            {
                for (int x = 0; x < columns; x++)
                {
                    RectangleF bounds = new RectangleF(x * cellWidht.X, y * cellWidht.Y, cellWidht.X, cellWidht.Y);
                    Buckets[x, y] = new Bucket<T>(bounds);
                }
            }
        }

        private static RectangleF CreateRectangleF(Microsoft.Xna.Framework.Rectangle bounds)
        {
            return new RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height);
        }

        public RectangleF Bounds
        {
            get;
            protected set;
        }

        public Bucket<T>[,] Buckets
        {
            get;
            protected set;
        }
    }
}
